package com.cwx.mychat.openai.config;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cwx.mychat.entity.po.UserInfo;
import com.cwx.mychat.mappers.UserInfoMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.support.ToolCallbacks;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 作者： cwx
 * 时间： 2025/1/9 18:37
 * 版本： 1.0
 * 注释：
 */
@Slf4j
@Configuration(proxyBeanMethods = false) //不使用代理
public class BookingToolsConfig {


    @Autowired
    private UserInfoMapper userInfoMapper;

    @Tool(name = "queryContact",description = "模糊查询联系人或者查询朋友或者用户")
    String queryContact(@ToolParam(description = "姓名或者昵称") String name){
        List<UserInfo> userInfos = userInfoMapper.selectList(new LambdaQueryWrapper<UserInfo>()
                .like(UserInfo::getNickName, name));
        if (userInfos.size() == 0) {
            return "没有找到联系人：" + name;
        }
        if(userInfos.size() == 1){
            return """
                    查询到联系人：%s
                    电子邮件：%s
                    地区：%s
                    生日：%s
                    电话号码： %s
                    """.formatted(userInfos.get(0).getNickName(),
                    userInfos.get(0).getEmail(),
                    userInfos.get(0).getAreaName(),
                    userInfos.get(0).getBirthday(),
                    userInfos.get(0).getPhone());
        }
        return """
                查询到类似的用户有：
                %s
                你具体要查哪一个呢？
                """.formatted(userInfos.stream().map(UserInfo::getNickName).collect(Collectors.joining(",")));
    }

    @Tool(description = "精确查询某一个具体的联系人，朋友或用户")
    String queryFriend(@ToolParam(description = "姓名或者昵称") String name){
        UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getNickName, name));
        if (userInfo == null) {
            return "没有找到联系人：" + name;
        }
        return """
                    查询到联系人：%s
                    电子邮件：%s
                    地区：%s
                    生日：%s
                    电话号码： %s
                    """.formatted(userInfo.getNickName(),
                userInfo.getEmail(),
                userInfo.getAreaName(),
                userInfo.getBirthday(),
                userInfo.getPhone());
    }


    @Tool(description = "获取用户所在时区的当前日期和时间")
    String getCurrentDateTime() {
        return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
    }

    @Tool(description = "获取用户所在地区的天气")
    String getWeather() {
        //调取天气接口
        return "今天天气晴朗，温度适宜，适宜外出";
    }

    @Tool(name = "search", description = "根据关键字搜索最新信息或者热点新闻，如果没提供关键字者直接搜索热点新闻")
    public String search(@ToolParam(description = "搜索的关键字", required = false) String keyword,
                         @ToolParam(description = "搜索的条数", required = false) Integer limit) throws InterruptedException {
        // 1. 扩大WebClient的缓冲限制（10MB）
        ExchangeStrategies strategies = ExchangeStrategies.builder()
                .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(10 * 1024 * 1024))
                .build();

        // 2. 设置请求的URL
        String baseUrl = "";
        String uri = "";
        baseUrl = keyword.isEmpty() ? "https://top.baidu.com" :  "https://www.baidu.com";
        uri = keyword.isEmpty() ? "/board?tab=realtime" : "/s?rtt=1&tn=news&word=" + keyword;
        // 3. 创建WebClient（模拟浏览器请求）
        WebClient client = WebClient.builder()
                .exchangeStrategies(strategies) // 应用新配置
                .baseUrl(baseUrl)
                .defaultHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
                .defaultHeader("Accept-Language", "zh-CN,zh;q=0.9")
                .defaultHeader("Referer", baseUrl)
                .build();

        // 4. 异步处理同步化（仅用于演示）
        CountDownLatch latch = new CountDownLatch(1);
        // 5. 发送请求并解析HTML
        // 使用 AtomicReference 存储最终结果（线程安全）
        AtomicReference<String> resultRef = new AtomicReference<>("===== 百度新闻搜索结果 =====");
        client.get()
                .uri(uri)
                .retrieve()
                .bodyToMono(String.class)
                .subscribe(html -> {
                    try {
                        String parsedResult;
                        if (!keyword.isEmpty()) {
                            parsedResult = parseNewsKeyFromHtml(html, limit);
                        } else {
                            parsedResult = parseNewsHotFromHtml(html, limit);
                        }
                        // 拼接结果
                        resultRef.set(resultRef.get() + parsedResult);
                    } finally {
                        latch.countDown();
                    }
                }, error -> {
                    resultRef.set(resultRef.get() + "\n请求失败: " + error.getMessage());
                    latch.countDown();
                });

        try {
            latch.await(); // 等待异步操作完成
            return resultRef.get(); // 返回最终拼接结果
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return resultRef.get() + "\n线程被中断";
        }
    }


    // 通过正则提取新闻标题和链接
    private static String parseNewsKeyFromHtml(String html, Integer limit) {
        // 匹配新闻条目（适配百度新闻最新HTML结构）
        Pattern newsPattern = Pattern.compile(
                "<div class=\"result-op c-container xpath-log new-pmd\".*?>.*?" +
                        "<h3 class=\"[^\"]*title[^\"]*\".*?<a href=\"(http[^\"]+)\"[^>]*>(.*?)</a>.*?" +
                        "<span class=\"c-color-gray2[^\"]*\"[^>]*>(.*?)</span>",
                Pattern.DOTALL
        );
        Matcher matcher = newsPattern.matcher(html);
        int count = 0;
        limit = limit != null ? limit:10;
        List<String> result = new ArrayList<>();
        // 提取新闻条目
        while (matcher.find() && count < limit) { // 最多提取10条
            String url = matcher.group(1);
            String title = matcher.group(2)
                    .replaceAll("<em>|</em>", "") // 清理高亮标签
                    .replaceAll("\\s+", " ")
                    .trim();
            String time = matcher.group(3);
            count++;
            result.add("标题: " + title + "\n链接: " + url + "\n时间: " + time + "\n");
        }
        if(count > 0){
            return "列出有" + count + "条"  + String.join("\n", result);
        }
        return "没有找到相关新闻, 请尝试其他关键字";
    }
    //提取新闻热点
    private static String parseNewsHotFromHtml(String html, Integer limit){
        // 先尝试从JSON数据解析（更稳定）
        limit = limit != null? limit:10;
        List<String> result = new ArrayList<>();
        try {
            // 提取JSON部分
            Pattern jsonPattern = Pattern.compile("<!--s-data:(.*?)-->");
            Matcher jsonMatcher = jsonPattern.matcher(html);
            if (jsonMatcher.find()) {
                String jsonStr = jsonMatcher.group(1).trim();
                System.out.println(jsonStr);
                ObjectMapper mapper = new ObjectMapper();
                JsonNode root = mapper.readTree(jsonStr);
                JsonNode items = root.path("data").path("cards").get(0).path("content");

                for (int i = 0; i < items.size() && i < limit; i++) {
                    String title = items.get(i).path("word").asText();
                    String url = items.get(i).path("url").asText();
                    String hotScore = items.get(i).path("hotScore").asText();
                    result.add("标题: " + title + "\n链接: " + url + "\n热度: " + hotScore + "\n");
                }
                return "列出有" + limit + "条"  + String.join("\n", result);
            }
        } catch (Exception e) {
            log.error("解析JSON数据失败: " + e.getMessage());
        }

        // 备用HTML解析方案（当JSON不可用时）
        Pattern htmlPattern = Pattern.compile(
                "<div class=\"category-wrap_iQLoo\".*?>.*?" +
                        "<div class=\"c-single-text-ellipsis\">(.*?)</div>.*?" +  // 标题
                        "<a href=\"(http[^\"]+)\".*?>.*?</a>.*?" +  // 链接
                        "<div class=\"hot-index_1Bl1a\">(.*?)</div>",  // 热度
                Pattern.DOTALL
        );

        Matcher matcher = htmlPattern.matcher(html);
        int count = 0;
        while (matcher.find() && count < limit) {
            String title = matcher.group(1).trim();
            String url = matcher.group(2);
            String hotScore = matcher.group(3);
            result.add("标题: " + title + "\n链接: " + url + "\n热度: " + hotScore + "\n");
            count++;
        }
        if (count > 0) {
            return "列出有" + limit + "条"  + String.join("\n", result);
        }
        return "没有找到相关新闻";

    }

}
